package com.hanggold.nx;

import com.hanggold.nx.bean.Person;
import org.junit.Test;

import java.beans.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author <a href="mailto:sunmch@163.com">smc</a>
 * @date 2019-07-31 19:04
 * @since
 **/
public class IntrospectorDemo {

    @Test
    public void loadBeanInfoTest() throws IntrospectionException {

        Map<Object, Object> map = new HashMap<Object, Object>();
        map.put("name", "张三");
        map.put("age", 30);

        BeanInfo beanInfo = Introspector.getBeanInfo(map.getClass());

        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

        for (PropertyDescriptor pd : propertyDescriptors) {
            System.out.printf("[属性名称: %s,属性类型: %s] \n", pd.getName(), pd.getPropertyType());
        }

        System.out.println("===========================================");

        MethodDescriptor[] methodDescriptors = beanInfo.getMethodDescriptors();
        for (MethodDescriptor md : methodDescriptors) {
            System.out.printf("[方法名称: %s,方法: %s] \n", md.getName(), md.getMethod());
        }

        System.out.println("===========================================");

        EventSetDescriptor[] eventSetDescriptors = beanInfo.getEventSetDescriptors();

        for (EventSetDescriptor esd : eventSetDescriptors) {
            System.out.printf("[监听名称: %s,监听类型: %s] \n", esd.getGetListenerMethod(), esd.getListenerType());
        }

        System.out.println("验证结束");

    }


    @Test
    public void propertyDecriptorTest() throws IntrospectionException {

        BeanInfo beanInfo = Introspector.getBeanInfo(Person.class, Object.class);

        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

        for (PropertyDescriptor pd : propertyDescriptors) {
            System.out.printf("[name: %s,readMethod: %s,writeMethod: %s ] \n", pd.getName(), pd.getReadMethod(), pd.getWriteMethod());
        }

    }


    @Test
    public void copyPropertiesTest() throws IntrospectionException, InvocationTargetException, IllegalAccessException {

        Map<String, PropertyDescriptor> soucrePropertyDescritor = new HashMap<>(10);

        Person source = new Person();
        source.setAge(1);
        source.setBirthday(new Date());
        source.setName("test copy");
        System.out.printf("[source:  %s]\n", source);

        BeanInfo beanInfoSource = Introspector.getBeanInfo(source.getClass(), Object.class);

        // 先把源信息存储起来,后续给目标对象属性赋值
        for (PropertyDescriptor propertyDescriptor : beanInfoSource.getPropertyDescriptors()) {
            soucrePropertyDescritor.putIfAbsent(propertyDescriptor.getName(), propertyDescriptor);
        }

        Person target = new Person();
        BeanInfo beanInfoTarget = Introspector.getBeanInfo(target.getClass(), Object.class);

        // 把源对象的数据写到目标对象属性值, 到此为止属性拷贝已经完成
        for (PropertyDescriptor pd : beanInfoTarget.getPropertyDescriptors()) {
            String name = pd.getName();
            Method writeMethod = pd.getWriteMethod();
            Method readMethod = soucrePropertyDescritor.get(name).getReadMethod();
            Object value = readMethod.invoke(source);
            writeMethod.invoke(target, value);
        }

        System.out.printf("[target： %s] \n",target);
    }


}
